<html>
<head><meta charset="utf-8"><title>Putting arena and allocated element in the same struct · t-compiler/help · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/index.html">t-compiler/help</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Putting.20arena.20and.20allocated.20element.20in.20the.20same.20struct.html">Putting arena and allocated element in the same struct</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="232954382"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Putting%20arena%20and%20allocated%20element%20in%20the%20same%20struct/near/232954382" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Léo Lanteri Thauvin <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Putting.20arena.20and.20allocated.20element.20in.20the.20same.20struct.html#232954382">(Apr 02 2021 at 21:28)</a>:</h4>
<p>I'm trying to store a <code>thir::Arena</code> and an allocated <code>&amp;thir::Expr</code> in a struct, like so:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">Thir</span><span class="o">&lt;'</span><span class="na">thir</span><span class="p">,</span><span class="w"> </span><span class="o">'</span><span class="na">tcx</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">thir</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="na">thir</span> <span class="nc">Expr</span><span class="o">&lt;'</span><span class="na">thir</span><span class="p">,</span><span class="w"> </span><span class="o">'</span><span class="na">tcx</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">arena</span>: <span class="nc">Arena</span><span class="o">&lt;'</span><span class="na">thir</span><span class="p">,</span><span class="w"> </span><span class="o">'</span><span class="na">tcx</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">build_thir</span><span class="o">&lt;'</span><span class="na">thir</span><span class="p">,</span><span class="w"> </span><span class="o">'</span><span class="na">tcx</span><span class="o">&gt;</span><span class="p">(</span><span class="w"></span>
<span class="w">    </span><span class="n">tcx</span>: <span class="nc">TyCtxt</span><span class="o">&lt;'</span><span class="na">tcx</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">owner_def</span>: <span class="nc">ty</span>::<span class="n">WithOptConstParam</span><span class="o">&lt;</span><span class="n">LocalDefId</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">expr</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="na">tcx</span> <span class="nc">hir</span>::<span class="n">Expr</span><span class="o">&lt;'</span><span class="na">tcx</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Thir</span><span class="o">&lt;'</span><span class="na">thir</span><span class="p">,</span><span class="w"> </span><span class="o">'</span><span class="na">tcx</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">arena</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Arena</span>::<span class="n">default</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">thir</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Cx</span>::<span class="n">new</span><span class="p">(</span><span class="n">tcx</span><span class="p">,</span><span class="w"> </span><span class="n">owner_def</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">arena</span><span class="p">).</span><span class="n">mirror_expr</span><span class="p">(</span><span class="n">expr</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">Thir</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">thir</span><span class="p">,</span><span class="w"> </span><span class="n">arena</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>But the borrow checker apparently complains that <code>arena</code> is borrowed:</p>
<div class="codehilite" data-code-language="Text only"><pre><span></span><code>error[E0515]: cannot return value referencing local variable `arena`
  --&gt; compiler/rustc_mir_build/src/thir/cx/mod.rs:29:5
   |
28 |     let thir = Cx::new(tcx, owner_def, &amp;arena).mirror_expr(expr);
   |                                        ------ `arena` is borrowed here
29 |     Thir { thir, arena }
   |     ^^^^^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function

error[E0505]: cannot move out of `arena` because it is borrowed
  --&gt; compiler/rustc_mir_build/src/thir/cx/mod.rs:29:18
   |
22 | pub fn build_thir&lt;'thir, 'tcx&gt;(
   |                   ----- lifetime `'thir` defined here
...
28 |     let thir = Cx::new(tcx, owner_def, &amp;arena).mirror_expr(expr);
   |                                        ------ borrow of `arena` occurs here
29 |     Thir { thir, arena }
   |     -------------^^^^^--
   |     |            |
   |     |            move out of `arena` occurs here
   |     returning this value requires that `arena` is borrowed for `'thir`
</code></pre></div>
<p>How can I explain to the compiler what I want? Is it possible? How do other parts of the compiler do this? The end goal is to be able to put the generated <code>Thir</code> body in a <code>Steal</code> for a query</p>



<a name="232955839"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Putting%20arena%20and%20allocated%20element%20in%20the%20same%20struct/near/232955839" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cjgillot <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Putting.20arena.20and.20allocated.20element.20in.20the.20same.20struct.html#232955839">(Apr 02 2021 at 21:43)</a>:</h4>
<p>Other parts of the compiler don't do this :)<br>
<code>rustc_data_structures::owning_ref</code> may be interesting.</p>



<a name="232955859"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Putting%20arena%20and%20allocated%20element%20in%20the%20same%20struct/near/232955859" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cjgillot <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Putting.20arena.20and.20allocated.20element.20in.20the.20same.20struct.html#232955859">(Apr 02 2021 at 21:43)</a>:</h4>
<p>At least the HIR does not.</p>



<a name="232958454"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Putting%20arena%20and%20allocated%20element%20in%20the%20same%20struct/near/232958454" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cjgillot <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Putting.20arena.20and.20allocated.20element.20in.20the.20same.20struct.html#232958454">(Apr 02 2021 at 22:18)</a>:</h4>
<p>Actually, I am not sure using an arena is the best solution for THIR. Since THIR is typically shallow and with only few types of nodes, I would have recommended the following:</p>
<div class="codehilite"><pre><span></span><code>struct Thir&lt;&#39;tcx&gt; {
  arms: IndexVec&lt;ArmId, Arm&lt;&#39;tcx&gt;&gt;,
  exprs: IndexVec&lt;ExprId, Expr&lt;&#39;tcx&gt;&gt;,
  field_exprs: IndexVec&lt;FieldExprId, FieldExpr&lt;&#39;tcx&gt;&gt;,
  stmts: IndexVec&lt;StmtId, Stmt&lt;&#39;tcx&gt;&gt;,
}
</code></pre></div>
<p>and use <code>ArmId</code>, <code>ExprId</code>... instead of pointers, and <code>Box&lt;InlineAsmOperand&lt;'tcx&gt;&gt;</code> instead of a reference.<br>
This should make borrow checking much easier, and consume a bit less memory (replace 64bit pointers by 32bit or 16bit indices).</p>



<a name="232993764"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Putting%20arena%20and%20allocated%20element%20in%20the%20same%20struct/near/232993764" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Léo Lanteri Thauvin <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Putting.20arena.20and.20allocated.20element.20in.20the.20same.20struct.html#232993764">(Apr 03 2021 at 09:20)</a>:</h4>
<p>So that would be closest to the MIR, correct? I'll go ahead and try to implement this approach, so that we can measure the perf implications of this change</p>



<a name="232993801"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Putting%20arena%20and%20allocated%20element%20in%20the%20same%20struct/near/232993801" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Léo Lanteri Thauvin <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Putting.20arena.20and.20allocated.20element.20in.20the.20same.20struct.html#232993801">(Apr 03 2021 at 09:21)</a>:</h4>
<p>Thanks for the help by the way <span aria-label="heart" class="emoji emoji-2764" role="img" title="heart">:heart:</span></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>